package org.apache.james.mime4j.decoder;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

final class Base64Encoder
{
  private static final byte[] ENCODING;
  private static final int FIRST_MASK = 16515072;
  private static final int FORTH_MASK = 63;
  private static final int MASK = 63;
  private static final int SECOND_MASK = 258048;
  private static final int THIRD_MASK = 4032;
  private final byte[] in;
  private final byte[] out;

  static
  {
    byte[] arrayOfByte = new byte[64];
    arrayOfByte[0] = 65;
    arrayOfByte[1] = 66;
    arrayOfByte[2] = 67;
    arrayOfByte[3] = 68;
    arrayOfByte[4] = 69;
    arrayOfByte[5] = 70;
    arrayOfByte[6] = 71;
    arrayOfByte[7] = 72;
    arrayOfByte[8] = 73;
    arrayOfByte[9] = 74;
    arrayOfByte[10] = 75;
    arrayOfByte[11] = 76;
    arrayOfByte[12] = 77;
    arrayOfByte[13] = 78;
    arrayOfByte[14] = 79;
    arrayOfByte[15] = 80;
    arrayOfByte[16] = 81;
    arrayOfByte[17] = 82;
    arrayOfByte[18] = 83;
    arrayOfByte[19] = 84;
    arrayOfByte[20] = 85;
    arrayOfByte[21] = 86;
    arrayOfByte[22] = 87;
    arrayOfByte[23] = 88;
    arrayOfByte[24] = 89;
    arrayOfByte[25] = 90;
    arrayOfByte[26] = 97;
    arrayOfByte[27] = 98;
    arrayOfByte[28] = 99;
    arrayOfByte[29] = 100;
    arrayOfByte[30] = 101;
    arrayOfByte[31] = 102;
    arrayOfByte[32] = 103;
    arrayOfByte[33] = 104;
    arrayOfByte[34] = 105;
    arrayOfByte[35] = 106;
    arrayOfByte[36] = 107;
    arrayOfByte[37] = 108;
    arrayOfByte[38] = 109;
    arrayOfByte[39] = 110;
    arrayOfByte[40] = 111;
    arrayOfByte[41] = 112;
    arrayOfByte[42] = 113;
    arrayOfByte[43] = 114;
    arrayOfByte[44] = 115;
    arrayOfByte[45] = 116;
    arrayOfByte[46] = 117;
    arrayOfByte[47] = 118;
    arrayOfByte[48] = 119;
    arrayOfByte[49] = 120;
    arrayOfByte[50] = 121;
    arrayOfByte[51] = 122;
    arrayOfByte[52] = 48;
    arrayOfByte[53] = 49;
    arrayOfByte[54] = 50;
    arrayOfByte[55] = 51;
    arrayOfByte[56] = 52;
    arrayOfByte[57] = 53;
    arrayOfByte[58] = 54;
    arrayOfByte[59] = 55;
    arrayOfByte[60] = 56;
    arrayOfByte[61] = 57;
    arrayOfByte[62] = 43;
    arrayOfByte[63] = 47;
    ENCODING = arrayOfByte;
  }

  public Base64Encoder(int paramInt)
  {
    this.in = new byte[paramInt];
    int i = 3 + (int)Math.floor(paramInt * 4 / 3.0F);
    this.out = new byte[i + 2 * (int)Math.floor(i / 76.0F)];
  }

  private int checkLineLength(byte[] paramArrayOfByte, int paramInt)
  {
    if ((paramInt == 76) || ((paramInt > 76) && ((paramInt - 2.0D * Math.floor(paramInt / 76.0F - 1F)) % 76.0D == 0D)))
    {
      int i = paramInt + 1;
      paramArrayOfByte[paramInt] = 13;
      paramInt = i + 1;
      paramArrayOfByte[i] = 10;
    }
    return paramInt;
  }

  private int encodeInputBuffer(byte[] paramArrayOfByte, int paramInt1, int paramInt2)
  {
    int i9;
    if (paramInt2 == 0)
    {
      i9 = 0;
      return i9;
    }
    int i = paramInt1 + paramInt2;
    int j = 0;
    for (int k = paramInt1; i - k > 2; k = i20)
    {
      int i16 = k + 1;
      int i17 = toInt(paramArrayOfByte[k]) << 16;
      int i18 = i16 + 1;
      int i19 = toInt(paramArrayOfByte[i16]) << 8;
      int i20 = i18 + 1;
      int i21 = toInt(paramArrayOfByte[i18]) | i17 | i19;
      int i22 = (0xFC0000 & i21) >> 18;
      int i23 = setResult(this.out, j, ENCODING[i22]);
      int i24 = (0x3F000 & i21) >> 12;
      int i25 = setResult(this.out, i23, ENCODING[i24]);
      int i26 = (i21 & 0xFC0) >> 6;
      int i27 = setResult(this.out, i25, ENCODING[i26]);
      int i28 = i21 & 0x3F;
      j = setResult(this.out, i27, ENCODING[i28]);
    }
    switch (i - k)
    {
    default:
    case 1:
    case 2:
    }
    while (true)
    {
      while (true)
      {
        while (true)
          i9 = j;
        (k + 1);
        int i10 = paramArrayOfByte[k] << 16;
        int i11 = (0xFC0000 & i10) >> 18;
        int i12 = setResult(this.out, j, ENCODING[i11]);
        int i13 = (0x3F000 & i10) >> 12;
        int i14 = setResult(this.out, i12, ENCODING[i13]);
        int i15 = setResult(this.out, i14, 61);
        j = setResult(this.out, i15, 61);
      }
      int l = k + 1;
      int i1 = paramArrayOfByte[k] << 16;
      (l + 1);
      int i2 = i1 + (paramArrayOfByte[l] << 8);
      int i3 = (0xFC0000 & i2) >> 18;
      int i4 = setResult(this.out, j, ENCODING[i3]);
      int i5 = (0x3F000 & i2) >> 12;
      int i6 = setResult(this.out, i4, ENCODING[i5]);
      int i7 = (i2 & 0xFC0) >> 6;
      int i8 = setResult(this.out, i6, ENCODING[i7]);
      j = setResult(this.out, i8, 61);
    }
  }

  private int setResult(byte[] paramArrayOfByte, int paramInt, byte paramByte)
  {
    int i = paramInt + 1;
    paramArrayOfByte[paramInt] = paramByte;
    return checkLineLength(paramArrayOfByte, i);
  }

  private int toInt(byte paramByte)
  {
    return (paramByte & 0xFF);
  }

  public void encode(InputStream paramInputStream, OutputStream paramOutputStream)
    throws IOException
  {
    while (true)
    {
      int j;
      do
      {
        int i = paramInputStream.read(this.in);
        if (i <= -1)
          return;
        j = encodeInputBuffer(this.in, 0, i);
      }
      while (j <= 0);
      paramOutputStream.write(this.out, 0, j);
    }
  }
}